﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using btom = Microsoft.BizTalk.ExplorerOM;
using System.Collections.Specialized;

//Important note. 
//This app must be compiled for 32bit execution only since BTS Explorer OM does not support 64bit 
//Yes I know, this sucks

namespace HenIT.BizTalk
{
    public partial class MainForm : Form
    {
        private string indentation = "\t";
        private string indentation2 = "\t\t";
        private string indentation3 = "\t\t\t";
        public MainForm()
        {
            InitializeComponent();
        }

        #region Form events
        private void Form1_Load(object sender, EventArgs e)
        {
            if (Properties.Settings.Default.NewVersion)
            {
                Properties.Settings.Default.Upgrade();
                Properties.Settings.Default.NewVersion = false;
                Properties.Settings.Default.Save();
            }
            txtServer.Text = Properties.Settings.Default.PreviousServer;
            txtDatabase.Text = Properties.Settings.Default.PreviousDatabase;
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Properties.Settings.Default.PreviousServer = txtServer.Text;
            Properties.Settings.Default.PreviousDatabase = txtDatabase.Text;
            Properties.Settings.Default.Save();
        } 
        #endregion

        #region BTS OM explorer methods
        private void GatherData()
        {
            try
            {
                richTextBox1.Visible = false;
                Application.DoEvents();
                // Create the root object and set the connection string
                using (btom.BtsCatalogExplorer catalog = new btom.BtsCatalogExplorer())
                {

                    catalog.ConnectionString = "SERVER=" + txtServer.Text + ";DATABASE=" + txtDatabase.Text + ";Integrated Security=SSPI";
                    //catalog.

                    richTextBox1.Clear();
                    richTextBox1.SuspendLayout();
                    
                    foreach (btom.Application app in catalog.Applications)
                    {
                        if (!app.IsSystem && (app.Name.Contains(txtApplication.Text) || txtApplication.Text.Length == 0))
                        {
                            RTFWriteHeading(app.Name);

                            if (chkReceivePorts.Checked)
                            {
                                RTFWriteHeading(indentation + "Receive ports");
                                if (app.ReceivePorts.Count == 0)
                                    RTFWriteLine(indentation2 + "None");
                                else
                                    foreach (btom.ReceivePort rp in app.ReceivePorts)
                                    {
                                        RTFWriteName(indentation2 + rp.Name);//
                                        foreach (string s in GetPortTrackingOptions(rp.Tracking))
                                        {
                                            RTFWriteLine(indentation3 + s);
                                        }
                                    }
                            }
                            if (chkSendPorts.Checked)
                            {
                                RTFWriteHeading(indentation + "Send ports");
                                if (app.SendPorts.Count == 0)
                                    RTFWriteLine(indentation2 + "None");
                                else
                                    foreach (btom.SendPort sp in app.SendPorts)
                                    {
                                        RTFWriteName(indentation2 + sp.Name); // + ":\t" + GetPortTrackingOptions(sp.Tracking));
                                        foreach (string s in GetPortTrackingOptions(sp.Tracking))
                                        {
                                            RTFWriteLine(indentation3 + s);
                                        }
                                    }
                            }

                            if (chkOrchestrations.Checked)
                            {
                                RTFWriteHeading(indentation + "Orchestrations");
                                if (app.Orchestrations.Count == 0)
                                    RTFWriteLine(indentation2 + "None");
                                else
                                    foreach (btom.BtsOrchestration o in app.Orchestrations)
                                    {
                                        RTFWriteName(indentation2 + o.FullName); //
                                        foreach (string s in GetOrchestrationTrackingOptions(o.Tracking))
                                        {
                                            RTFWriteLine(indentation3 + s);
                                        }
                                    }
                            }

                            if (chkPipelines.Checked)
                            {
                                RTFWriteHeading(indentation + "Pipelines");
                                if (app.Pipelines.Count == 0)
                                    RTFWriteLine(indentation2 + "None");
                                else
                                    foreach (btom.Pipeline p in app.Pipelines)
                                    {
                                        RTFWriteName(indentation2 + p.FullName);
                                        foreach (string s in GetPipelineTrackingOptions(p.Tracking))
                                        {
                                            RTFWriteLine(indentation3 + s);
                                        }
                                    }
                            }

                            //app.Schemas[0].AlwaysTrackAllProperties
                        }
                    }
                    richTextBox1.ResumeLayout();
                    richTextBox1.SelectionStart = 0;
                    richTextBox1.SelectionLength = 0;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                richTextBox1.Visible = true;
            }
        }

        private StringCollection GetPipelineTrackingOptions(btom.PipelineTrackingTypes tracking)
        {
            StringCollection output = new StringCollection();
            if ((int)tracking == 0)
            {
                output.Add("none");
            }
            else
            {
                if (IsPipelineTrackingType(tracking, btom.PipelineTrackingTypes.ServiceStartEnd))
                    output.Add(btom.PipelineTrackingTypes.ServiceStartEnd.ToString());
                if (IsPipelineTrackingType(tracking, btom.PipelineTrackingTypes.MessageSendReceive))
                    output.Add(btom.PipelineTrackingTypes.MessageSendReceive.ToString());
                if (IsPipelineTrackingType(tracking, btom.PipelineTrackingTypes.InboundMessageBody))
                    output.Add(btom.PipelineTrackingTypes.InboundMessageBody.ToString());
                if (IsPipelineTrackingType(tracking, btom.PipelineTrackingTypes.OutboundMessageBody))
                    output.Add(btom.PipelineTrackingTypes.OutboundMessageBody.ToString());
                if (IsPipelineTrackingType(tracking, btom.PipelineTrackingTypes.PipelineEvents))
                    output.Add(btom.PipelineTrackingTypes.PipelineEvents.ToString());
            }
            return output;
        }
        private bool IsPipelineTrackingType(btom.PipelineTrackingTypes tracking, btom.PipelineTrackingTypes compareTo)
        {
            return ((tracking & compareTo) == compareTo);
        }

        private StringCollection GetPortTrackingOptions(btom.TrackingTypes tracking)
        {
            StringCollection output = new StringCollection();
            if ((int)tracking == 0)
            {
                output.Add("none");
            }
            else
            {
                if (IsTrackingTypes(tracking, btom.TrackingTypes.BeforeReceivePipeline))
                    output.Add(btom.TrackingTypes.BeforeReceivePipeline.ToString());
                if (IsTrackingTypes(tracking, btom.TrackingTypes.AfterReceivePipeline))
                    output.Add(btom.TrackingTypes.AfterReceivePipeline.ToString());
                if (IsTrackingTypes(tracking, btom.TrackingTypes.BeforeSendPipeline))
                    output.Add(btom.TrackingTypes.BeforeSendPipeline.ToString());
                if (IsTrackingTypes(tracking, btom.TrackingTypes.AfterSendPipeline))
                    output.Add(btom.TrackingTypes.AfterSendPipeline.ToString());
                if (IsTrackingTypes(tracking, btom.TrackingTypes.TrackPropertiesBeforeReceivePipeline))
                    output.Add(btom.TrackingTypes.TrackPropertiesBeforeReceivePipeline.ToString());
                if (IsTrackingTypes(tracking, btom.TrackingTypes.TrackPropertiesAfterReceivePipeline))
                    output.Add(btom.TrackingTypes.TrackPropertiesAfterReceivePipeline.ToString());
                if (IsTrackingTypes(tracking, btom.TrackingTypes.TrackPropertiesBeforeSendPipeline))
                    output.Add(btom.TrackingTypes.TrackPropertiesBeforeSendPipeline.ToString());
                if (IsTrackingTypes(tracking, btom.TrackingTypes.TrackPropertiesAfterSendPipeline))
                    output.Add(btom.TrackingTypes.TrackPropertiesAfterSendPipeline.ToString());

            }
            return output;
        }
        private bool IsTrackingTypes(btom.TrackingTypes tracking, btom.TrackingTypes compareTo)
        {
            return ((tracking & compareTo) == compareTo);
        }

        private StringCollection GetOrchestrationTrackingOptions(btom.OrchestrationTrackingTypes tracking)
        {
            StringCollection output = new StringCollection();
            if ((int)tracking == 0)
            {
                output.Add("none");
            }
            else
            {
                if (IsTrackingTypes(tracking, btom.OrchestrationTrackingTypes.ServiceStartEnd))
                    output.Add(btom.OrchestrationTrackingTypes.ServiceStartEnd.ToString());
                if (IsTrackingTypes(tracking, btom.OrchestrationTrackingTypes.MessageSendReceive))
                    output.Add(btom.OrchestrationTrackingTypes.MessageSendReceive.ToString());
                if (IsTrackingTypes(tracking, btom.OrchestrationTrackingTypes.InboundMessageBody))
                    output.Add(btom.OrchestrationTrackingTypes.InboundMessageBody.ToString());
                if (IsTrackingTypes(tracking, btom.OrchestrationTrackingTypes.OutboundMessageBody))
                    output.Add(btom.OrchestrationTrackingTypes.OutboundMessageBody.ToString());
                if (IsTrackingTypes(tracking, btom.OrchestrationTrackingTypes.OrchestrationEvents))
                    output.Add(btom.OrchestrationTrackingTypes.OrchestrationEvents.ToString());
                if (IsTrackingTypes(tracking, btom.OrchestrationTrackingTypes.TrackPropertiesForIncomingMessages))
                    output.Add(btom.OrchestrationTrackingTypes.TrackPropertiesForIncomingMessages.ToString());
                if (IsTrackingTypes(tracking, btom.OrchestrationTrackingTypes.TrackPropertiesForOutgoingMessages))
                    output.Add(btom.OrchestrationTrackingTypes.TrackPropertiesForOutgoingMessages.ToString());
            }
            return output;
        }
        private bool IsTrackingTypes(btom.OrchestrationTrackingTypes tracking, btom.OrchestrationTrackingTypes compareTo)
        {
            return ((tracking & compareTo) == compareTo);
        }
        #endregion

        #region RTF writing
        private void RTFWriteHeading(string text)
        {
            AddFormatRTFLine(text, FontStyle.Bold, 12, Color.Maroon);
        }
        private void RTFWriteName(string text)
        {
            AddFormatRTFLine(text, FontStyle.Regular, 10, SystemColors.WindowText);
        }
        private void RTFWriteLine(string text)
        {
            AddFormatRTFLine(text, FontStyle.Regular, 8, Color.Blue);
        }
        private void AddFormatRTFLine(string text, FontStyle fs, float fontsize, Color textColor)
        {
            richTextBox1.AppendText(text);
            if (text.Length > 0)
            {
                richTextBox1.SelectionStart = richTextBox1.Text.Length - text.Length;
                richTextBox1.SelectionLength = text.Length;
                richTextBox1.SelectionFont = new Font("Microsoft Sans Serif", fontsize, fs);
                richTextBox1.SelectionColor = textColor;
            }
            richTextBox1.AppendText("\r\n");
        } 
        #endregion

        #region Button events
        private void cmdStart_Click(object sender, EventArgs e)
        {
            try
            {
                GatherData();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        #endregion

        #region Context Menu events
        private void copyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBox1.Copy();
        }

        private void selectAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            richTextBox1.SelectAll();
        } 

        private void saveOutputAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (saveFileDialog1.ShowDialog() == DialogResult.OK)
            {
                richTextBox1.SaveFile(saveFileDialog1.FileName);
            }
        }
        #endregion


    }
}
